package service

import (
	"errors"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"guns-go/factory"
	"guns-go/global"
	"guns-go/model"
	"guns-go/model/request"
	"guns-go/model/response"
	"guns-go/utils"
)

func DeleteSysOpLog() error {

	tx := global.GVA_DB.Begin()
	err := tx.Where("1=1").Delete(model.SysOpLog{}).Error

	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}

func SaveSysOpLog(sysOpLog *model.SysOpLog) error {
	return global.GVA_DB.Create(sysOpLog).Error
}

func ExecuteOperationLog(sysOpLog *model.SysOpLog, c *gin.Context) error {

	err, sysOpLog := genBaseSysOpLog(sysOpLog, c)

	if err != nil {
		global.GVA_LOG.Error("gen base sys op log error", zap.String("err", err.Error()))
		return err
	}

	//成功和异常日志区分
	if c.Writer.Status() == 200 {
		factory.CreateSysOperationLog(sysOpLog, c)
	} else {
		sysOpLog.Result = ""
		factory.CreateSysExceptionLog(sysOpLog, c)
	}

	//异步记录日志
	go SaveSysOpLog(sysOpLog)

	return nil
}

//构建基础操作日志
func genBaseSysOpLog(sysOpLog *model.SysOpLog, c *gin.Context) (error, *model.SysOpLog) {

	if c != nil {
		ip := c.ClientIP()
		address := ""
		browser := c.Request.UserAgent()
		os := ""
		url := c.Request.URL.Path
		method := c.Request.Method

		factory.GenBaseSysOpLog(sysOpLog, ip, address, browser, os, url, method)
		return nil, sysOpLog
	} else {
		return errors.New("当前请求参数为空或数据缺失，请联系管理员"), nil
	}
}

func SysOpLogPage(sysOpLogParam *request.SysOpLogParam, c *gin.Context) (err error, result *response.PageResult) {

	var sysOpLogSlice []*model.SysOpLog
	db := global.GVA_DB

	if sysOpLogParam != nil {

		//根据名称模糊查询
		if sysOpLogParam.Name != "" {
			db = db.Where("name like ?", "%"+sysOpLogParam.Name+"%")
		}

		//根据操作类型查询
		if sysOpLogParam.OpType != nil {
			db = db.Where("op_type =  ?", sysOpLogParam.OpType)
		}

		//根据是否成功查询
		if sysOpLogParam.Success != "" {
			db = db.Where("success =  ?", sysOpLogParam.Success)
		}
	}
	var totalCount int64

	err = db.Find(&sysOpLogSlice).Count(&totalCount).Error

	if err != nil {
		return err, nil
	}

	pageNo, pageSize, db := utils.DefaultPage(c, db)

	err = db.Find(&sysOpLogSlice).Error

	if err != nil {
		return err, nil
	}

	return err, utils.CoverToPageResult(pageNo, pageSize, totalCount, sysOpLogSlice)
}
